package com.alit.http.httpserver;
/**
 * @author litong
 * @date 2019年4月18日_下午1:43:26 
 * @version 1.0 
 */

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SimpleHttpServer {
	private static final int POOL_MUITIPLE = 4;
	@SuppressWarnings("unused")
	private int port;
	private ServerSocketChannel serverSocketChannel;
	private ExecutorService executorService;

	public SimpleHttpServer(int port) {
		this.port = port;
		int nThreads = Runtime.getRuntime().availableProcessors() * POOL_MUITIPLE;
		executorService = Executors.newFixedThreadPool(nThreads);
		try {
			serverSocketChannel = ServerSocketChannel.open();
		} catch (IOException e) {
			log.error("打开失败");
			e.printStackTrace();
		}
		try {
			serverSocketChannel.socket().setReuseAddress(true);
		} catch (SocketException e) {
			log.error("设置失败");
			e.printStackTrace();
		}
		try {
			serverSocketChannel.socket().bind(new InetSocketAddress(port));
		} catch (IOException e) {
			log.error("端口绑定失败");
			e.printStackTrace();
		}
	}

	/**
	 * 启动服务
	 * 
	 * @param port
	 */
	public static void startServer(final int port) {
		log.info("服务开始启动:" + port);
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				SimpleHttpServer httpServer = new SimpleHttpServer(port);
				httpServer.service();
			}
		});
		log.info("服务启动成功");
		t.start();
	}

	/**
	 * 处理请求
	 */
	public void service() {
		while (true) {
			SocketChannel socketChannel = null;
			try {
				socketChannel = serverSocketChannel.accept();
			} catch (IOException e) {
				e.printStackTrace();
			}
			SocketChannelHandler socketChannelHandler = new SocketChannelHandler(socketChannel);
			executorService.execute(socketChannelHandler);
		}
	}
}